package com.ape.mapsa.common;

import java.io.ByteArrayInputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import org.apache.log4j.Logger;
import org.primefaces.context.RequestContext;
import org.primefaces.event.SelectEvent;
import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.MenuModel;
import org.primefaces.model.StreamedContent;
import org.primefaces.model.UploadedFile;
import org.springframework.dao.DataIntegrityViolationException;

import com.ape.mapsa.produccion.model.Color;
import com.ape.mapsa.produccion.service.IProduccionService;

@ManagedBean(name = "colorsMB")
@ViewScoped
public class ColorsBean extends BeanCRUD implements Serializable {

	private static final long serialVersionUID = 5591853302070050847L;

	private static final Logger log = Logger.getLogger(ColorsBean.class);

	@ManagedProperty("#{produccionService}")
	private IProduccionService prodService;

	private List<Color> colors;
	private List<Color> colorsFiltrados = new ArrayList<Color>();
	private Color selectedColor = null;
	private boolean rowSelected = false;

	private StreamedContent image;

	private Color result;

	private Color newColor;

	private UploadedFile uploadedFile;

	private boolean showAbm;

	private boolean editing;

	@PostConstruct
	public void initialize() {
		log.info("Initializing Color Bean");
		colors = new ArrayList<Color>();
		newColor = new Color();
		setColors(prodService.getAllColors());
		colorsFiltrados.addAll(colors);
	}

	public void addColor() {
		newColor.setCreated(new Date());
		if (newColor.getId() == null) {
			prodService.saveColor(newColor);
			colors.add(newColor);
			colorsFiltrados.add(newColor);
		} else {
			prodService.updateColor(newColor);
		}
		setShowAbm(false);
		setEditing(false);
		FacesContext context = FacesContext.getCurrentInstance();
		FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Color agregado", newColor.getDescripcion());
		RequestContext.getCurrentInstance().update("addColorForm:abm_id");
		RequestContext.getCurrentInstance().update("addColorForm:colors:colors");
		context.addMessage(null, msg);
	}

	public void rowSelected(SelectEvent event) {
		log.debug("rowSelected");
		setRowSelected(selectedColor != null);
		result = selectedColor;
	}

	@Override
	public void save(ActionEvent event) {
		addColor();
	}

	@Override
	public void update(ActionEvent event) {

	}

	@Override
	public void create(ActionEvent event) {
		log.info("Color nuevo");
		newColor = new Color();
		setShowAbm(true);
		setEditing(false);
		RequestContext.getCurrentInstance().update("addColorForm:abm_id");
		RequestContext.getCurrentInstance().scrollTo("addColorForm:abm_id");
	}

	@Override
	public void edit(ActionEvent event) {
		log.info("Editando Color " + selectedColor);
		newColor = selectedColor;
		if (newColor != null) {
			setShowAbm(true);
			setEditing(true);
			RequestContext.getCurrentInstance().update("addColorForm:abm_id");
			RequestContext.getCurrentInstance().scrollTo("addColorForm:abm_id");
		} else {
			FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_WARN, "Selecciono nula", "Debe seleccionar un color de la tabla.");
			FacesContext.getCurrentInstance().addMessage(null, msg);
		}
	}

	@Override
	public void delete(ActionEvent event) {
		log.info("Editando Color " + selectedColor);
		newColor = selectedColor;
		if (newColor != null) {
			setShowAbm(false);
			setEditing(false);
			RequestContext.getCurrentInstance().update("addColorForm:abm_id");
			try {
				prodService.deleteColor(newColor);
				colors.remove(selectedColor);
				colorsFiltrados.remove(selectedColor);
				RequestContext.getCurrentInstance().update("addColorForm:colors:colors");
			} catch (Exception ex) {
				if (ex instanceof DataIntegrityViolationException) {
					FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_WARN, "Color",
							"Esta siendo usado en el sistema, y no podrá ser eliminado.");
					FacesContext.getCurrentInstance().addMessage(null, msg);
				}
			}
		} else {
			FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_WARN, "Selecciono nula", "Debe seleccionar un color de la tabla.");
			FacesContext.getCurrentInstance().addMessage(null, msg);
		}
	}

	@Override
	public MenuModel getMenuModel() {
		return menuModel;
	}

	public void getColor(ActionEvent actionEvent) {
		result = selectedColor;
	}

	public IProduccionService getProdService() {
		return prodService;
	}

	public void setProdService(IProduccionService prodService) {
		this.prodService = prodService;
	}

	public Color getNewColor() {
		return newColor;
	}

	public void setNewColor(Color newColor) {
		this.newColor = newColor;
	}

	public List<Color> getColors() {
		return colors;
	}

	public void setColors(List<Color> colors) {
		this.colors = colors;
	}

	@PreDestroy
	public void predestroy() {
		log.info("destruyendo colors bean");
	}

	public Color getSelectedColor() {
		return selectedColor;
	}

	public void setSelectedColor(Color selectedColor) {
		this.selectedColor = selectedColor;
	}

	public List<Color> getColorsFiltrados() {
		return colorsFiltrados;
	}

	public void setColorsFiltrados(List<Color> colorsFiltrados) {
		this.colorsFiltrados = colorsFiltrados;
	}

	public boolean isRowSelected() {
		return rowSelected;
	}

	public void setRowSelected(boolean rowSelected) {
		this.rowSelected = rowSelected;
	}

	public Color getResult() {
		return result;
	}

	public void setResult(Color result) {
		this.result = result;
	}

	public UploadedFile getUploadedFile() {
		return uploadedFile;
	}

	public void setUploadedFile(UploadedFile uploadedFile) {
		this.uploadedFile = uploadedFile;
	}

	public StreamedContent getImage() {
		if (image != null) {
			log.info("returning image " + image.getName());
		} else {
			log.info("null image");

			return new DefaultStreamedContent(new ByteArrayInputStream(new byte[] {}), "");
		}
		return image;
	}

	public void setImage(StreamedContent image) {
		this.image = image;
	}

	public boolean isShowAbm() {
		return showAbm;
	}

	public void setShowAbm(boolean showAbm) {
		this.showAbm = showAbm;
	}

	public boolean isEditing() {
		return editing;
	}

	public void setEditing(boolean editing) {
		this.editing = editing;
	}

}
